#include "fileoper.h"

FileOperSer::FileOperSer()
{
    FileName_ = "";
    StuInfoMap_.clear(); 
}

int FileOperSer::OnInit(const string& FileName)
{
    int ret = SetFileName(FileName);
    if(ret != 0)
    {
        printf("FileOperSvr::OnInIt Failed\n");
        return ret;
    }
    //读文件
    ret = ReadFromFile();
    if(ret != 0)
    {
        printf("FileOperSvr::OnInIt Failed\n");
        return ret;
    }
    return 0;
}


int FileOperSer::EraseFromMap(int index)
{
    auto itor = StuInfoMap_.find(index);
    if(itor == StuInfoMap_.end())
    {
        printf("FileOperSer::EraseFromMap failed %d\n", __LINE__);
        return -1;
    }
    StuInfoMap_.erase(itor);
    return 0;
}

int FileOperSer::FindFromMap(int index, StuInfo* si)
{
    if(index < 0)
    {
        printf("FileOperSvr::FindFromMap %d\n", __LINE__);
        return -1;
    }
    auto itor = StuInfoMap_.find(index); 
    if(itor == StuInfoMap_.end())
    {
        printf("FileOperSvr::FindFromMap %d\n", __LINE__);
        return -1;
    }

    *si = itor->second;
    return 0;
}

int FileOperSer::WriteToFile()
{
    //将数据写到一个新的文件当中去,主要是更新没有点到了但是没有来的次数，下次再重启服务的时候，就读的是这个新的文件，对于抽签的话，主要是想用这个算一个比重
    //删除老的童鞋信息的文件
    //重命名新的文件
    unlink(FileName_.c_str());

    fstream file(FileName_, ios::out | ios::app);
    if(!file.is_open())
    {
        perror("重写文件失败");
        return -1;
    }
    auto itor = StuInfoMap_.begin();
    while(itor != StuInfoMap_.end())
    {
        string tmpdata = "";
        tmpdata += itor->second.StuName;
        tmpdata += " ";
        tmpdata += itor->second.OutOfClassCount;
        tmpdata += "\n";

        file.write(tmpdata.data(), tmpdata.size());
        itor++;
    }
    file.close();
    return 0;
}

int FileOperSer::GetMapSize()
{
    return StuInfoMap_.size();
}

int FileOperSer::UpdateMapData(const int index, bool IsExist)
{
    //如果只有一个人的时候，index为0
    if(index < 0)
    {
        return -1;
    }
    auto itor = StuInfoMap_.find(index); 
    if(itor == StuInfoMap_.end())
    {
        GetErrorFileAndNum();
        return -1;
    }

    if(IsExist)
    {
        //itor->second.OutOfClassCount = "0";
        //只要童鞋在，就-1，如果他之前缺课很多每次就只是减1，而不是直接归零了
        //如果本来的值就是0，还是-1，这样将被抽到的几率降低
        itor->second.OutOfClassCount = to_string(atoi(itor->second.OutOfClassCount.c_str()) - 1);
    }
    else
    {
        itor->second.OutOfClassCount = to_string(atoi(itor->second.OutOfClassCount.c_str()) + 1);
    }
    return 0;
}

int FileOperSer::SetFileName(const string& FileName)
{
    if(FileName.size() <= 0)
    {
        printf("FileOperSer::SetFileName 传入的FileName为null\n");
        return -1;
    }
    FileName_ = FileName;
    return 0;
}

int FileOperSer::ReadFromFile()
{
    ifstream file(FileName_, ios::in);
    if(!file.is_open())
    {
        perror("FileOperSer::ReadFromFile");
        return -1;
    }

    string Line = "";
    int StuCount = 0;
    while(getline(file,Line))
    {
        vector<string> StuInfVec;
        StuInfVec.clear();
        SpiltLine(Line, " ", &StuInfVec);

        if(StuInfVec.size() <= 1)
        {
            printf("请核实该行数据，%s\n", Line.c_str());
            continue;
        }

        StuInfo si;
        si.StuName = StuInfVec[0];
        si.OutOfClassCount = StuInfVec[1];
        StuInfoMap_.insert(pair<int, StuInfo>(StuCount, si));
        StuCount++;
    }
    return 0;
}
//切割字符串
void FileOperSer::SpiltLine(string& Line, const string& SplitChar, vector<string>* OutValueVec)
{
    //token_compress_off 是当有连续的分割符的时候不要一起处理，反之token_compress_on:当有连续的分割符的时候可以一起处理，看成是一个
    boost::split(*OutValueVec, Line, boost::is_any_of(SplitChar), boost::token_compress_off);
}


//查询的管理功能
void FileOperSer::ShowAllDataFromMap()
{
    auto itor = StuInfoMap_.begin();
    while(itor != StuInfoMap_.end())
    {
        printf("name:%s, OutOfClassCount:%s\n", itor->second.StuName.c_str(), itor->second.OutOfClassCount.c_str());
        itor++;
    }
}
